package com.blue.crawler;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.blue.core.file.ClassScanner;
import com.blue.crawler.annotation.CrawlerClassHandler;
import com.blue.crawler.util.CrawlerInvoker;


/**
 * 爬虫核心类
 * 
 * @author zhengj
 * @since 1.0 2016年9月22日
 */
public class Crawler implements InitializingBean, DisposableBean, ApplicationContextAware
{
	private static Logger logger = LoggerFactory.getLogger(Crawler.class);

	private int thread = 1; // 抓取线程数
	private String root; // 下载文件根目录
	private CrawlerInvoker invoker; // HTTP调用器
	private ApplicationContext applicationContext;
	private CrawlerStarter starter;
	private List<String> packageList;
	
	public Crawler()
	{
	}
	
	/**
	 * 开始爬虫
	 */
	public void start()
	{
		if (root == null || root.isEmpty())
			throw new CrawlerException("下载文件根目录不能为空");
		
		starter = new CrawlerStarter(thread, root, invoker, applicationContext);
		starter.start();
	}
	
	/**
	 * 结束爬虫
	 */
	public void stop()
	{
		if (starter != null)
		{
			starter.stop();
		}
	}
	
	public void setThread(int thread)
	{
		this.thread = thread;
	}

	public void setRoot(String root)
	{
		this.root = root;
	}

	public String getRoot()
	{
		return root;
	}

	public void setInvoker(CrawlerInvoker invoker)
	{
		this.invoker = invoker;
	}

	public void setScanPackages(List<String> packageList)
	{
		this.packageList = packageList;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
	{
		this.applicationContext = applicationContext;
	}

	@Override
	public void afterPropertiesSet() throws Exception
	{
		logger.info("扫描包：{}", packageList);
		ClassScanner scanner = new ClassScanner();
		scanner.setClassHandler(new CrawlerClassHandler());
		scanner.scan(true, packageList);
		
		if (invoker == null)
		{
			invoker = new CrawlerInvoker();
			logger.info("找不到 HttpInvoker 配置，自动实例化");
		}
	}

	@Override
	public void destroy() throws Exception
	{
		this.stop();
		if (invoker != null)
		{
			invoker.destroy();
		}
	}
	
}
